import { TComponent } from '@material/typeing';
import { BaseEventOrig, Image, ImageProps as TImageProps } from '@tarojs/components';
import { FC, ReactNode, isValidElement, useCallback, useEffect, useState } from 'react';
import { setStyleSize } from '@/utils';
import { isImageUrl } from './util';
import { isString } from '@material/helpers';
import $style from './index.scss';
import Loading from '../loading';
export interface ImageProps extends Omit<TImageProps, 'style' | 'className'>, TComponent {
    size?: number | string;
    width?: string | number;
    height?: string | number;
    loading?: boolean | ReactNode;
    error?: boolean | ReactNode;
}
export enum ImageStatusType {
    LOADING = 'loading',
    ERROR = 'error',
    LOADED = 'loaded'
}

const KImage: FC<ImageProps> = function (props) {
    const {
        className,
        src,
        error = true,
        loading,
        size,
        width,
        height,
        style,
        onLoad,
        onError,
        ...rest
    } = props;
    const [status, setStatus] = useState(ImageStatusType.LOADING);
    const handleLoad = (e: BaseEventOrig<TImageProps.onLoadEventDetail>) => {
        setStatus(ImageStatusType.LOADED);
        onLoad && onLoad(e);
    };
    const handleError = (e: BaseEventOrig<TImageProps.onErrorEventDetail>) => {
        setStatus(ImageStatusType.ERROR);
        onError && onError(e);
    };
    const renderLoading = useCallback(() => {
        if (!loading) return null;
        if (
            typeof loading === 'boolean' &&
            loading === true &&
            status === ImageStatusType.LOADING
        ) {
            return (
                <div className={$style.loading}>
                    <Loading></Loading>
                </div>
            );
        }
        if (isValidElement(loading) && status === ImageStatusType.LOADING) {
            return <div className={$style.loading}>{loading}</div>;
        }
        return null;
    }, [loading, status]);
    const renderErrorImg = useCallback(() => {
        if (status !== ImageStatusType.ERROR) return null;
        if (typeof error === 'boolean' && error === true) {
            return (
                <div
                    className={$style.error}
                    style={{ backgroundColor: '#F4F4F4' }}
                ></div>
            );
        }
        if (isString(error) && isImageUrl(error)) {
            return (
                <div
                    className={$style.error}
                    style={{ backgroundImage: `url(${error})` }}
                ></div>
            );
        }
        if (isString(error)) {
            return (
                <div
                    className={$style.error}
                    style={{ backgroundColor: error }}
                ></div>
            );
        }
        if (isValidElement(error)) {
            return <div className={$style.error}>{error}</div>;
        }
        return null;
    }, [error, status]);
    useEffect(() => {
        if (isString(src) === false || src.trim().length === 0) {
            handleError({} as any);
        }
    }, [src]);
    return (
        <div
            className={[$style.image, className]}
            style={{ ...setStyleSize(width || size, height || size), ...style }}
        >
            <Image
                mode='aspectFill'
                {...rest}
                className={$style['image-inner']}
                src={src}
                onLoad={(e) => handleLoad(e)}
                onError={(e) => handleError(e)}
            ></Image>
            {renderLoading()}
            {renderErrorImg()}
        </div>
    );
};

export default KImage;
